package com.wiener.web.managebeans;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;

import org.apache.log4j.Logger;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

import com.wiener.core.beans.Academica;
import com.wiener.core.beans.Historico;
import com.wiener.core.beans.Notas;
import com.wiener.core.beans.Obligaciones;
import com.wiener.core.domain.Concepto;
import com.wiener.core.domain.Detalle;
import com.wiener.core.domain.Entidad;
import com.wiener.core.domain.Recibo;
import com.wiener.core.services.IntegrationServices;

@ManagedBean(name = "obligacionesManagedBean")
@ApplicationScoped
public class ObligacionesManagedBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private static final Logger logger = Logger
			.getLogger(ObligacionesManagedBean.class);

	private List<Obligaciones> obligaciones;
	private List<Historico> historicos;
	private List<Academica> situacionAcademica;
	private List<Entidad> lugarPagos;
	private List<Entidad> instituciones;
	private List<Entidad> tipoDocumentos;
	private List<Entidad> monedas;
	private List<Entidad> periodos;
	private List<Detalle> detalles;
	private List<Concepto> conceptos;
	private List<Notas> notas;
	List<Recibo> recibos;

	boolean insertar = false;
	boolean actualizar = false;

	private String periodo;

	private Object[] selectedRecibos;
	private Object[] selectedDetalle;
	public Recibo recibo;
	public Detalle detalleNuevo;

	@ManagedProperty(value = "#{integrationServices}")
	private IntegrationServices integrationServices;

	private FacesContext context;

	private String codigoInstitucion;
	private String lugarPago;
	private String tipoDescuento;
	private String moneda;
	private String tipoCambio;
	private String fechaHora;
	private String sede;
	private String serie;

	/*
	 * public String codigoConcepto; public String descripcionConcepto; public
	 * String nCuota="1"; public String mes="1"; public String cantidad = "1";
	 * public String monto="0"; public String descuento="0"; public String
	 * subtotal="0";
	 */

	public void limpiar() {
		try {
			logger.info(" contructor ");
			recibo = new Recibo();
			obligaciones = new ArrayList<Obligaciones>();
			historicos = new ArrayList<Historico>();
			situacionAcademica = new ArrayList<Academica>();
			notas = new ArrayList<Notas>();
			recibos = new ArrayList<Recibo>();
			periodo = "";
			detalles = new ArrayList<Detalle>();
			conceptos = new ArrayList<Concepto>();
			detalleNuevo = new Detalle();
			context = FacesContext.getCurrentInstance();
			recibo = new Recibo();
			obligaciones = new ArrayList<Obligaciones>();
			historicos = new ArrayList<Historico>();
			situacionAcademica = new ArrayList<Academica>();
			recibos = new ArrayList<Recibo>();
			periodo = "";

			conceptos = new ArrayList<Concepto>();
			fechaHora = integrationServices.buscarFechaHora();
			sede = integrationServices
					.buscarCodigoSede(obtenerNombreUsuario(SecurityContextHolder
							.getContext()));

			detalles = new ArrayList<Detalle>();
			instituciones = new ArrayList<Entidad>();
			lugarPagos = new ArrayList<Entidad>();
			tipoDocumentos = new ArrayList<Entidad>();
			monedas = new ArrayList<Entidad>();
			codigoInstitucion = "";
			lugarPago = "";
			tipoDescuento = "";
			moneda = "";
			tipoCambio = "";

			lugarPagos = integrationServices.buscarLugarPago();

			instituciones.addAll(integrationServices.buscarInstitucion());

			tipoDocumentos = integrationServices.buscarTipoDocumento();
			monedas = integrationServices.buscarMoneda();
			setInsertar(false);
			setActualizar(false);
		} catch (Exception e) {
			e.printStackTrace();
		}
		logger.info(" fin contructor ");

	}

	public ObligacionesManagedBean() {
		logger.info(" contructor ");
		recibo = new Recibo();
		obligaciones = new ArrayList<Obligaciones>();
		historicos = new ArrayList<Historico>();
		situacionAcademica = new ArrayList<Academica>();
		recibos = new ArrayList<Recibo>();
		periodo = "";
		detalles = new ArrayList<Detalle>();
		conceptos = new ArrayList<Concepto>();
		detalleNuevo = new Detalle();
		logger.info(" fin contructor ");
	}

	@PostConstruct
	public void inicializar() {
		try {
			logger.info(" Inicializando pagina ");
			context = FacesContext.getCurrentInstance();
			recibo = new Recibo();
			obligaciones = new ArrayList<Obligaciones>();
			historicos = new ArrayList<Historico>();
			situacionAcademica = new ArrayList<Academica>();
			recibos = new ArrayList<Recibo>();
			periodo = "";
			detalleNuevo = new Detalle();
			conceptos = new ArrayList<Concepto>();
			fechaHora = integrationServices.buscarFechaHora();
			sede = integrationServices
					.buscarCodigoSede(obtenerNombreUsuario(SecurityContextHolder
							.getContext()));

			detalles = new ArrayList<Detalle>();

			lugarPagos = integrationServices.buscarLugarPago();
			instituciones = integrationServices.buscarInstitucion();
			tipoDocumentos = integrationServices.buscarTipoDocumento();
			monedas = integrationServices.buscarMoneda();

			logger.info(" Fin inicio pagina ");
			setInsertar(false);
			setActualizar(false);
		} catch (Exception e) {
			e.printStackTrace();
			context.addMessage(null, new FacesMessage(
					" Error Cangando Pagina ", e.getMessage()));
		}
	}

	public void buscarSerie() {
		try {
			serie = integrationServices.buscarNumeroDocumento(
					obtenerNombreUsuario(SecurityContextHolder.getContext()),
					null, codigoInstitucion, tipoDescuento, recibo.getCodigo());
			recibo.setSerie(serie);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private static String obtenerNombreUsuario(SecurityContext securityContex)
			throws Exception {

		if (securityContex == null) {
			throw new Exception(" Your Session has been expired ");
		}
		Authentication authentication = securityContex.getAuthentication();

		if (authentication == null) {
			throw new Exception(" Autenticacion failure ");
		}
		String name = authentication.getName();
		logger.info(" nombre usuario  " + name);
		return name;
	}

	public void buscarTipoCambio() {
		BigDecimal cambio = integrationServices.buscarTipoCambio(moneda);
		if (cambio != null) {
			tipoCambio = cambio.toString();
		}

	}

	public void generarObligaciones() {
		try {
			context = FacesContext.getCurrentInstance();
			logger.info(" Generando Obligaciones ");
			logger.info(" codigo = " + recibo.getCodigo());
			logger.info("periodo = " + periodo);
			String resultado = this.integrationServices.generarObligaciones(
					recibo.getCodigo(),
					obtenerNombreUsuario(SecurityContextHolder.getContext()),
					periodo);
			context.addMessage(null, new FacesMessage("Generando Obligaciones",
					resultado));
			obligaciones = integrationServices
					.buscarObligacionesPorCodigo(recibo.getCodigo());
			logger.info(" Finalizando Generando Obligaciones ");
		} catch (Exception e) {
			e.printStackTrace();
			context.addMessage(null, new FacesMessage(
					" Error Generando Obligaciones ", e.getMessage()));
		}

	}

	public void buscarCodigo() {

		logger.info(" inicio buscarCodigo = " + recibo.getCodigo());
		context = FacesContext.getCurrentInstance();
		try {
			recibos = integrationServices.buscarInformeAlumnoPorCodigo(recibo
					.getCodigo());
			if (recibos == null || recibos.isEmpty()) {
				this.recibo = new Recibo();
				obligaciones = new ArrayList<Obligaciones>();
				historicos = new ArrayList<Historico>();
				situacionAcademica = new ArrayList<Academica>();
				recibos = new ArrayList<Recibo>();
				periodo = "";

				conceptos = new ArrayList<Concepto>();
				fechaHora = integrationServices.buscarFechaHora();
				sede = integrationServices
						.buscarCodigoSede(obtenerNombreUsuario(SecurityContextHolder
								.getContext()));

				detalles = new ArrayList<Detalle>();

				lugarPagos = integrationServices.buscarLugarPago();
				instituciones = integrationServices.buscarInstitucion();
				tipoDocumentos = integrationServices.buscarTipoDocumento();
				monedas = integrationServices.buscarMoneda();
				return;
			}
			for (Iterator<Recibo> iterator = recibos.iterator(); iterator
					.hasNext();) {
				recibo = (Recibo) iterator.next();
				setRecibo(recibo);
				break;
			}
			lugarPagos = integrationServices.buscarLugarPago();
			instituciones = integrationServices.buscarInstitucion();
			tipoDocumentos = integrationServices.buscarTipoDocumento();
			monedas = integrationServices.buscarMoneda();
			fechaHora = integrationServices.buscarFechaHora();

			recibo.setSerie(integrationServices.buscarNumeroDocumento(
					obtenerNombreUsuario(SecurityContextHolder.getContext()),
					null, codigoInstitucion, recibo.getTipoDescuento(),
					recibo.getCodigo()));
			recibo.setRuc(integrationServices.buscarRuc(recibo.getCodigo()));
			buscarSerie();
			detalles = new ArrayList<Detalle>();

			obligaciones = integrationServices
					.buscarObligacionesPorCodigo(recibo.getCodigo());
			historicos = integrationServices.buscarHistoricosPorCodigo(recibo
					.getCodigo());
			situacionAcademica = integrationServices
					.buscarSituacionAcademicaPorCodigo(recibo.getCodigo());
			notas = integrationServices.buscarNotas(recibo.getCodigo());
			periodos = integrationServices.buscarPeriodos(recibo.getCodigo());
			setInsertar(false);
			setActualizar(false);
		} catch (Exception e) {
			e.printStackTrace();
			context.addMessage(null, new FacesMessage(
					" Error Buscando por Codigo ", e.getMessage()));
		}

		logger.info(" fin buscarCodigo ");
	}

	public void buscarDni() {
		logger.info(" inicio buscardni");

		try {
			context = FacesContext.getCurrentInstance();
			recibos = integrationServices.buscarInformeAlumnoPorDni(recibo
					.getDocumentoIdentidad());
			if (recibos == null || recibos.isEmpty()) {
				return;
			}
			for (Iterator<Recibo> iterator = recibos.iterator(); iterator
					.hasNext();) {
				recibo = (Recibo) iterator.next();
				setRecibo(recibo);
				break;
			}
			lugarPagos = integrationServices.buscarLugarPago();
			instituciones = integrationServices.buscarInstitucion();
			tipoDocumentos = integrationServices.buscarTipoDocumento();
			monedas = integrationServices.buscarMoneda();
			fechaHora = integrationServices.buscarFechaHora();
			recibo.setSerie(integrationServices.buscarNumeroDocumento(
					obtenerNombreUsuario(SecurityContextHolder.getContext()),
					null, codigoInstitucion, recibo.getTipoDescuento(),
					recibo.getCodigo()));
			recibo.setRuc(integrationServices.buscarRuc(recibo.getCodigo()));
			buscarSerie();
			detalles = new ArrayList<Detalle>();

			obligaciones = integrationServices
					.buscarObligacionesPorCodigo(recibo.getCodigo());
			historicos = integrationServices.buscarHistoricosPorCodigo(recibo
					.getCodigo());
			situacionAcademica = integrationServices
					.buscarSituacionAcademicaPorCodigo(recibo.getCodigo());
			periodos = integrationServices.buscarPeriodos(recibo.getCodigo());
			setInsertar(false);
			setActualizar(false);
		} catch (Exception e) {
			e.printStackTrace();
			context.addMessage(null, new FacesMessage(
					" Error Buscando por DNI ", e.getMessage()));
		}

		logger.info(" fin buscardni ");

	}

	public void obtenerConceptos() {
		conceptos = integrationServices.buscarConceptos(codigoInstitucion);

	}

	public void cargar() {
		try {
						
			context = FacesContext.getCurrentInstance();
			System.out.println(detalleNuevo.getConcepto());
			for (Iterator iterator = conceptos.iterator(); iterator.hasNext();) {
				Concepto type = (Concepto) iterator.next();
				if (detalleNuevo.getConcepto().equals(
						type.getServicioClasificacion())) {
					detalleNuevo.setDescripcionConcepto(type
							.getDescServicioClasificacion());
					break;
				}
			}
			BigDecimal monto1 = integrationServices.buscarPrecios(
					codigoInstitucion, detalleNuevo.getConcepto(), moneda,
					recibo.getCodigo());
			detalleNuevo.setMonto(monto1.toString());
			detalleNuevo.setSubtotal(""
					+ (Integer.parseInt(detalleNuevo.getMonto()) * Integer
							.parseInt(detalleNuevo.getCantidad())));
		} catch (Exception e) {
			e.printStackTrace();
			context.addMessage(null,
					new FacesMessage(" Error En la pagina ", e.getMessage()));
		}

	}

	public void actualizarFila1() {
		setActualizar(true);
		setInsertar(false);
	}

	public void actualizarfila() {

		Detalle valor = null;

		if (detalles != null && !detalles.isEmpty()) {
			for (int i = 0; i < detalles.size(); i++) {
				valor = detalles.get(i);
				if (valor.getConcepto().equals(detalleNuevo.getConcepto())) {
					detalles.remove(i);
					detalles.add(detalleNuevo);
				}
			}
		}

	}

	public void insertarfila() {

		setInsertar(true);
		setActualizar(false);

		if (detalles != null && !detalles.isEmpty()) {
			detalles.add(detalleNuevo);
		} else {
			detalles = new ArrayList<Detalle>();
			detalles.add(detalleNuevo);
		}

	}

	public void insertarDetalle() {
		/*
		 * codigoConcepto =""; descripcionConcepto =""; nCuota =""; mes ="";
		 * cantidad = "1"; monto =""; descuento =""; subtotal = "";
		 */
		detalleNuevo = new Detalle();
		System.out.println(" codigo intitucion = " + codigoInstitucion);
		conceptos = integrationServices.buscarConceptos(codigoInstitucion);
		setInsertar(true);
		setActualizar(false);

	}

	public void eliminarDetalle() {

		System.out.println(" codigo intitucion = " + codigoInstitucion);
		Detalle detalle;
		int[] indices = new int[selectedDetalle.length];

		for (int i = 0; i < selectedDetalle.length; i++) {
			if (selectedDetalle[i] instanceof Detalle) {
				detalle = (Detalle) selectedDetalle[i];
				for (int j = 0; j < detalles.size(); j++) {
					Detalle type = (Detalle) detalles.get(j);
					if (detalle.getIndex() == type.getIndex()) {
						indices[i] = j;
					}
				}
			}
		}

		for (int i = 0; i < indices.length; i++) {
			detalles.remove(indices[i]);
		}
	}

	public void calularSubtotal() {
		if (detalleNuevo.getDescuento() != null
				&& !"".equals(detalleNuevo.getDescuento())) {
			detalleNuevo
					.setSubtotal(""
							+ (Integer.parseInt(detalleNuevo.getCantidad())
									* Integer.parseInt(detalleNuevo.getMonto()) - Integer
										.parseInt(detalleNuevo.getDescuento())));
		} else {
			detalleNuevo.setSubtotal(""
					+ Integer.parseInt(detalleNuevo.getCantidad())
					* Integer.parseInt(detalleNuevo.getDescuento()));

		}

	}

	
	public void guardadDetalle() {

		context = FacesContext.getCurrentInstance();

		/*
		 * if(selectedDetalle== null || selectedDetalle.length == 0){
		 * context.addMessage(null, new FacesMessage(" Detalle Guardado ",
		 * "Debe Seleccionar algun registro para guardar.")); return; }
		 */

		try {
			for (int i = 0; i < detalles.size(); i++) {
				Detalle type = (Detalle) detalles.get(i);
				integrationServices
						.guardarDetalle(
								codigoInstitucion,
								lugarPago,
								obtenerNombreUsuario(SecurityContextHolder
										.getContext()),

								tipoDescuento,
								serie,
								recibo.getRuc(),
								getMoneda(),
								getTipoCambio(),
								recibo.getCodigo(),
								obtenerNombreUsuario(SecurityContextHolder
										.getContext()),
								"" + (i + 1),
								type.getConcepto(),
								type.getnCuota() != null
										&& !"".equals(type.getnCuota()) ? type
										.getnCuota() : null,
								type.getMes() != null
										&& !"".equals(type.getMes()) ? type
										.getMes() : null,
								type.getCantidad() != null
										&& !"".equals(type.getCantidad()) ? type
										.getCantidad() : null,
								type.getMonto() != null
										&& !"".equals(type.getMonto()) ? type
										.getMonto() : null,
								type.getDescuento() != null
										&& !"".equals(type.getDescuento()) ? type
										.getDescuento() : null, type
										.getSubtotal(), detalles.size());

			}
			context.addMessage(null, new FacesMessage(" Detalle Guardado ",
					"Detalle Guardado"));
			selectedDetalle = new Object[0];
		} catch (Exception e) {
			e.printStackTrace();
			context.addMessage(null, new FacesMessage(
					" Error Detalle Guardado ", e.getMessage()));
		}

	}

	public void enviarDetallePagos() {
		context = FacesContext.getCurrentInstance();
		int index = 1;
		try {
			detalles = new ArrayList<Detalle>();
			Detalle detalle = new Detalle();
			System.out.println(" enviarDetallePagos ");
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, new FacesMessage("enviarDetallePagos",
					"enviarDetallePagos"));
			Obligaciones obligaciones = null;
			System.out.println("codigo institucion = "
					+ recibo.getCodigoInstitucion());
			System.out.println("codigo institucion = " + codigoInstitucion);
			conceptos = integrationServices.buscarConceptos(codigoInstitucion);
			for (int i = 0; i < selectedRecibos.length; i++) {
				if (selectedRecibos[i] instanceof Obligaciones) {
					obligaciones = (Obligaciones) selectedRecibos[i];
					System.out.println(" periodo " + obligaciones.getPeriodo());
					System.out.println(" persona " + obligaciones.getPersona());
					detalle = new Detalle(index, obligaciones.getCodigo(),
							obligaciones.getCodigo(),
							obligaciones.getDescripcionConcepto(),
							obligaciones.getMonto(), obligaciones.getnCuota(),
							obligaciones.getMes(), "1", null,
							obligaciones.getMonto());
					detalles.add(detalle);
					index++;
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
			context.addMessage(null, new FacesMessage(
					" Error Cangando Pagina ", e.getMessage()));
		}

	}

	public List<Concepto> getConceptos() {
		return conceptos;
	}

	public void setConceptos(List<Concepto> conceptos) {
		this.conceptos = conceptos;
	}

	public List<Detalle> getDetalles() {
		return detalles;
	}

	public void setDetalles(List<Detalle> detalles) {
		this.detalles = detalles;
	}

	public String getPeriodo() {
		return periodo;
	}

	public void setPeriodo(String periodo) {
		this.periodo = periodo;
	}

	public List<Entidad> getPeriodos() {
		return periodos;
	}

	public void setPeriodos(List<Entidad> periodos) {
		this.periodos = periodos;
	}

	public Object[] getSelectedRecibos() {
		return selectedRecibos;
	}

	public void setSelectedRecibos(Object[] selectedRecibos) {
		this.selectedRecibos = selectedRecibos;
	}

	public List<Academica> getSituacionAcademica() {
		return situacionAcademica;
	}

	public void setSituacionAcademica(List<Academica> situacionAcademica) {
		this.situacionAcademica = situacionAcademica;
	}

	public List<Obligaciones> getObligaciones() {
		return obligaciones;
	}

	public void setObligaciones(List<Obligaciones> obligaciones) {
		this.obligaciones = obligaciones;
	}

	public List<Entidad> getLugarPagos() {
		return lugarPagos;
	}

	public void setLugarPagos(List<Entidad> lugarPagos) {
		this.lugarPagos = lugarPagos;
	}

	public List<Entidad> getInstituciones() {
		return instituciones;
	}

	public void setInstituciones(List<Entidad> instituciones) {
		this.instituciones = instituciones;
	}

	public List<Entidad> getTipoDocumentos() {
		return tipoDocumentos;
	}

	public void setTipoDocumentos(List<Entidad> tipoDocumentos) {
		this.tipoDocumentos = tipoDocumentos;
	}

	public List<Entidad> getMonedas() {
		return monedas;
	}

	public void setMonedas(List<Entidad> monedas) {
		this.monedas = monedas;
	}

	public List<Historico> getHistoricos() {
		return historicos;
	}

	public void setHistoricos(List<Historico> historicos) {
		this.historicos = historicos;
	}

	public Recibo getRecibo() {
		return recibo;
	}

	public void setRecibo(Recibo recibo) {
		this.recibo = recibo;
	}

	public IntegrationServices getIntegrationServices() {
		return integrationServices;
	}

	public void setIntegrationServices(IntegrationServices integrationServices) {
		this.integrationServices = integrationServices;
	}

	public String getCodigoInstitucion() {
		return codigoInstitucion;
	}

	public void setCodigoInstitucion(String codigoInstitucion) {
		this.codigoInstitucion = codigoInstitucion;
	}

	public String getLugarPago() {
		return lugarPago;
	}

	public void setLugarPago(String lugarPago) {
		this.lugarPago = lugarPago;
	}

	public String getTipoDescuento() {
		return tipoDescuento;
	}

	public void setTipoDescuento(String tipoDescuento) {
		this.tipoDescuento = tipoDescuento;
	}

	public String getMoneda() {
		return moneda;
	}

	public void setMoneda(String moneda) {
		this.moneda = moneda;
	}

	public String getTipoCambio() {
		return tipoCambio;
	}

	public void setTipoCambio(String tipoCambio) {
		this.tipoCambio = tipoCambio;
	}

	public String getFechaHora() {
		return fechaHora;
	}

	public void setFechaHora(String fechaHora) {
		this.fechaHora = fechaHora;
	}

	public Object[] getSelectedDetalle() {
		return selectedDetalle;
	}

	public void setSelectedDetalle(Object[] selectedDetalle) {
		this.selectedDetalle = selectedDetalle;
	}

	public String getSede() {
		return sede;
	}

	public void setSede(String sede) {
		this.sede = sede;
	}

	public String getSerie() {
		return serie;
	}

	public void setSerie(String serie) {
		this.serie = serie;
	}

	public List<Notas> getNotas() {
		return notas;
	}

	public void setNotas(List<Notas> notas) {
		this.notas = notas;
	}

	public List<Recibo> getRecibos() {
		return recibos;
	}

	public void setRecibos(List<Recibo> recibos) {
		this.recibos = recibos;
	}

	public Detalle getDetalleNuevo() {
		if (detalleNuevo == null)
			this.detalleNuevo = new Detalle();
		
		return detalleNuevo;
	}

	public void setDetalleNuevo(Detalle detalleNuevo) {
		this.detalleNuevo = detalleNuevo;
	}

	public boolean isInsertar() {
		return insertar;
	}

	public void setInsertar(boolean insertar) {
		this.insertar = insertar;
	}

	public boolean isActualizar() {
		return actualizar;
	}

	public void setActualizar(boolean actualizar) {
		this.actualizar = actualizar;
	}

}
